#include "config.h"

#define DBG_SUBSYS S_LIBSTORAGE

#include "sysutil.h"
#include "lich_qos.h"

static qos_config_t *__qos_config__ = NULL;


static inline int __opt_init(nodectl_option_t *opt, const char *path, int dv)
{
        int ret;
        char buf[MAX_NAME_LEN];

        ret = opt_nodectl_init2(opt);
        if (unlikely(ret))
                GOTO(err_ret, ret);

        sprintf(buf, "%d", dv);
        ret = opt->start(opt, path, buf, NULL);
        if (unlikely(ret))
                GOTO(err_ret, ret);

        return 0;
err_ret:
        return ret;
}

int qos_config_init()
{
        int ret;

        if (__qos_config__ == NULL) {
                ret = ymalloc((void **)&__qos_config__, sizeof(qos_config_t));
                if (unlikely(ret))
                        GOTO(err_ret, ret);

                __qos_config__->task_max = RECOVERY_TASK_MAX;
                __qos_config__->wait_max = RECOVERY_WAIT_THROT;

                // __qos_config__->iops_dft = RECOVERY_QOS_IOPS_DEFAULT;
                // __qos_config__->iops_min = RECOVERY_QOS_IOPS_MIN;
                // __qos_config__->iops_step = RECOVERY_QOS_STEP;
                // __qos_config__->iops_dist = RECOVERY_QOS_DIST;

                ret = __opt_init(&__qos_config__->opt_iops_onoff, "qos/iops_onoff", 1);
                if (unlikely(ret))
                        UNIMPLEMENTED(__DUMP__);

                ret = __opt_init(&__qos_config__->opt_iops_dft, "qos/iops_dft", RECOVERY_QOS_IOPS_DEFAULT);
                if (unlikely(ret))
                        UNIMPLEMENTED(__DUMP__);

                ret = __opt_init(&__qos_config__->opt_iops_min, "qos/iops_min", RECOVERY_QOS_IOPS_MIN);
                if (unlikely(ret))
                        UNIMPLEMENTED(__DUMP__);

                ret = __opt_init(&__qos_config__->opt_iops_step, "qos/iops_step", RECOVERY_QOS_STEP);
                if (unlikely(ret))
                        UNIMPLEMENTED(__DUMP__);

                ret = __opt_init(&__qos_config__->opt_iops_dist, "qos/iops_dist", RECOVERY_QOS_DIST);
                if (unlikely(ret))
                        UNIMPLEMENTED(__DUMP__);

                ret = __opt_init(&__qos_config__->opt_iops_exp, "qos/iops_exp", RECOVERY_QOS_EXP);
                if (unlikely(ret))
                        UNIMPLEMENTED(__DUMP__);

                ret = __opt_init(&__qos_config__->opt_iops_jitter, "qos/iops_jitter", RECOVERY_QOS_JITTER);
                if (unlikely(ret))
                        UNIMPLEMENTED(__DUMP__);
        }

        return 0;
err_ret:
        return ret;
}

inline int qos_config_get_iops_onoff()
{
        int ret = __qos_config__->opt_iops_onoff.value;
        itorange(&ret, 0, 1);
        return ret;
}

inline int qos_config_get_iops_dft()
{
        int ret = __qos_config__->opt_iops_dft.value;
        itorange(&ret, 100, 1000);
        return ret;
}

inline int qos_config_get_iops_min()
{
        int ret = __qos_config__->opt_iops_min.value;
        itorange(&ret, 1, 100);
        return ret;
}

inline int qos_config_get_iops_step()
{
        int ret = __qos_config__->opt_iops_step.value;
        itorange(&ret, 1, 100);
        return ret;
}

inline int qos_config_get_iops_dist()
{
        int ret = __qos_config__->opt_iops_dist.value;
        itorange(&ret, 100, 1000);
        return ret;
}

inline int qos_config_get_iops_exp()
{
        int ret = __qos_config__->opt_iops_exp.value;
        itorange(&ret, 50, 100);
        return ret;
}

inline int qos_config_get_iops_jitter()
{
        int ret = __qos_config__->opt_iops_jitter.value;
        itorange(&ret, 0, 100);
        return ret;
}
